<template>
  <div class="goods-container">
    <search-part @changePage="changePage"></search-part>
    <goods-sift></goods-sift>
    <div
      class="goods-swipe"
      ref="swipe"
      @touchstart.capture="touchStart"
      @touchmove.capture="touchMove"
      @touchend.capture="touchEnd"
    >
      <transition :name="transitionName" mode="out-in">
        <keep-alive>
          <router-view class="swipe-page" />
        </keep-alive>
      </transition>
    </div>
  </div>
</template>

<script>
import SearchPart from "@/components/SearchPart.vue";
import { mapState } from "vuex";
import GoodsSift from "@/components/GoodsSift.vue";
export default {
  components: { SearchPart, GoodsSift },
  data() {
    return {
      transitionName: "slide-left", // 过度动画名称 滑动时才有过度动画
      touch: {}, // 保存着起始位置x1和变化的位置x2
      currentDistance: 0, // 上一个touch事件完成后，已滑动距离。
      totalDiff: 0, // 总滑动距离
      timeId: null,
    };
  },
  computed: {
    ...mapState(["touchStatus", "goTop"]),
  },
  methods: {
    //点击首页返回顶部
    goTops() {
      if (this.timeId) return;
      const dom = this.$refs.swipe;
      //滚动距离过短不进行滚动
      if (dom.scrollTop <= 340) {
        this.$store.commit("setGoTop", false);
        return;
      }
      let num = 0;
      //滚动动画
      this.timeId = setInterval(() => {
        num += 5;
        dom.scrollTop -= num;
        if (dom.scrollTop <= 0) {
          dom.scrollTop = 0;
          this.$store.commit("setGoTop", false);
          clearInterval(this.timeId);
          this.timeId = null;
          return;
        }
      }, 20);
    },
    //点击上方导航切换页面
    changePage(name) {
      if (this.$route.name === name) return;
      this.$store.commit("setTouchStatus", true);
      //判断点击的导航
      if (name === "GoodsList") {
        this.transitionName = "slide-right";
        this.$router.replace({ name });
      } else {
        this.transitionName = "slide-left";
        this.$router.replace({ name });
      }
    },
    /**
     * 左右滑动动态切换路由
     */
    //记录手指摁下时的位置
    touchStart(ev) {
      let touch = ev.changedTouches[0];
      this.touch.x1 = touch.pageX;
      this.touch.y1 = touch.pageY;
    },
    //记录手指移动的距离
    touchMove(ev) {
      let touch = ev.changedTouches[0];
      this.touch.x2 = touch.pageX;
      this.touch.y2 = touch.pageY;
      let w = Math.abs(this.touch.x2 - this.touch.x1);
      let h = Math.abs(this.touch.y2 - this.touch.y1);
      // 部分安卓手机可能会有兼容问题
      if (w > h) {
        window.event.preventDefault();
      }
      this.currentDistance = this.touch.x2 - this.touch.x1; // 差值，表示滑动过程中手指移动的距离
    },
    //手指抬起计算并判断是否可切换页面
    touchEnd(ev) {
      let touch = ev.changedTouches[0];
      this.touch.x2 = touch.pageX;
      this.touch.y2 = touch.pageY;
      let diff = this.touch.x2 - this.touch.x1; // 手指触摸结束位置的水平移动差值
      let diffY = this.touch.y2 - this.touch.y1; // 竖直方向的差值
      this.totalDiff = diff + this.currentDistance;
      // 正切得到弧度转换为角度
      let angel = (Math.atan2(Math.abs(diffY), Math.abs(this.totalDiff)) * 180) / Math.PI; // 90为垂直滑动 需要一定差值
      if (this.touchStatus) {
        // 这个参数是为了处理页面banner的滑动，水平滑动和手势的冲突
        if (angel < 50 && this.totalDiff < -25 && this.$route.name !== "GoodsCollect") {
          // 小于为左滑 左滑到右边（商品收藏）
          this.transitionName = "slide-left";
          this.$router.replace("/goods/goodscollect");
        } else if (angel < 35 && this.totalDiff > 25 && this.$route.name !== "GoodsList") {
          // 大于为右滑 右滑到左边（商品列表）
          this.transitionName = "slide-right";
          this.$router.replace("/goods/goodslist");
        }
      }
      //默认阻止滑动，开启滑动
      this.$store.commit("setTouchStatus", true);
    },
  },
  watch: {
    goTop(newVal, odlVal) {
      if (newVal === true) {
        this.goTops();
      }
    },
  },
};
</script>

<style lang="scss" scoped>
@import "../css/GoodsView.scss";
</style>
